#include "stdafx.h"
#include "CppUnitTest.h"

#include "MxPluginManager\MxPluginManager1.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageComputePluginLib.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageCompute.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageComputeFnDef.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageComputeFn.h"

#include "..\..\PublicInterfaces\PluginICPopenCV\OCV-Dev-ProductID.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace PluginICPopenCVTest
{
	TEST_CLASS(TransformImageTest)
	{
	private:
		MxPluginManager			*_pluginMngr;
		MxPluginLib				*_plugin;
		IImageComputePluginLib	*_lib;
		IImageCompute		    *_icp;
		IImageComputeFnDef		*_fnDef;
		IImageComputeFn			*_fn;

	public:

		TEST_METHOD_INITIALIZE(TransformImgInit)
		{
			_pluginMngr = new MxPluginManager();
			if (_pluginMngr->RefreshPluginsInRootFolder(SID_ImageProc, true) == true)
			{
				if ((_plugin = _pluginMngr->GetPlugin(PRODID_PluginICPopenCV)) != nullptr)
				{
					if ((_lib = static_cast<IImageComputePluginLib *>(_plugin->CreateClassInstance(IImageComputePluginLibIID::Guid()))) != nullptr)
					{
						if((_icp = _lib->GetIImageCompute()) != nullptr)
						{
							GUID fnID = MxGUID::ConvertFromString("{B6627EBE-A40E-48F2-BB3B-EE49856C035D}");
							_fnDef =_icp->GetIImageComputeFnDef(fnID);
							_fn =_icp->GetIImageComputeFn(fnID);
						}
					}
				}
			}
		}

		TEST_METHOD_CLEANUP(TransformImgDeinit)
		{
			if(_fn != nullptr)
				_fn->DestroyPtr();
			_fn = nullptr;

			if(_fnDef!= nullptr)
				_fnDef->DestroyPtr();
			_fnDef = nullptr;

			if(_icp != nullptr)
				_icp->DestroyPtr();
			_icp = nullptr;

			if(_lib != nullptr)
				_lib->DestroyPtr();
			_lib = nullptr;

			if (_pluginMngr != nullptr)
				delete _pluginMngr;
			_pluginMngr = nullptr;
		}
		
		TEST_METHOD(TransformImgCreateTest)
		{
			Assert::IsNotNull(_fnDef);
			Assert::IsTrue(_fnDef->IsValid());

			Assert::IsNotNull(_fn);
			Assert::IsTrue(_fn->IsValid());
		}

		TEST_METHOD(TransformImgFnDefParamsTest)
		{
			Assert::IsNotNull(_fnDef);
			Assert::IsTrue(_fnDef->IsValid());

			Assert::AreEqual("TransformImg", _fnDef->GetLabel());
			Assert::AreEqual("Affine transformation of image", _fnDef->GetDescription());
			Assert::AreEqual("Common", _fnDef->GetToolboxClass());
			Assert::AreEqual("Transform", _fnDef->GetToolboxLabel());
			Assert::AreEqual(24, _fnDef->GetToolboxIconClassOffset());

			Assert::AreEqual(15, _fnDef->GetParamCount(IImageComputeFnDef::Direction::Input));
			Assert::AreEqual(0, _fnDef->GetParamCount(IImageComputeFnDef::Direction::Output));
			Assert::AreEqual(2, _fnDef->GetParamCount(IImageComputeFnDef::Direction::IO));

			Assert::AreEqual("StopProc", _fnDef->GetParamName(IImageComputeFnDef::Direction::IO, 0));
			Assert::AreEqual("ImageRef", _fnDef->GetParamName(IImageComputeFnDef::Direction::IO, 1));
			Assert::AreEqual("RootFolder", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 0));
			Assert::AreEqual("IJC", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 1));
			Assert::AreEqual("IJF", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 2));
			Assert::AreEqual("SrcFirstPointX", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 3));
			Assert::AreEqual("SrcFirstPointY", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 4));
			Assert::AreEqual("SrcSecondPointX", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 5));
			Assert::AreEqual("SrcSecondPointY", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 6));
			Assert::AreEqual("SrcThirdPointX", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 7));
			Assert::AreEqual("SrcThirdPointY", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 8));
			Assert::AreEqual("DstFirstPointX", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 9));
			Assert::AreEqual("DstFirstPointY", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 10));
			Assert::AreEqual("DstSecondPointX", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 11));
			Assert::AreEqual("DstSecondPointY", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 12));
			Assert::AreEqual("DstThirdPointX", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 13));
			Assert::AreEqual("DstThirdPointY", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 14));

			Assert::IsTrue(IImageComputeFnDef::Direction::IO == _fnDef->GetParamDirection("StopProc"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("RootFolder"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("IJC"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("IJF"));
			Assert::IsTrue(IImageComputeFnDef::Direction::IO == _fnDef->GetParamDirection("ImageRef"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("SrcFirstPointX"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("SrcFirstPointY"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("SrcSecondPointX"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("SrcSecondPointY"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("SrcThirdPointX"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("SrcThirdPointY"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("DstFirstPointX"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("DstFirstPointY"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("DstSecondPointX"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("DstSecondPointY"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("DstThirdPointX"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("DstThirdPointY"));

			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("StopProc")) == IImageComputeFnDef::ParamType::Bool);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("RootFolder")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("IJC")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("IJF")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("ImageRef")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("SrcFirstPointX")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("SrcFirstPointY")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("SrcSecondPointX")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("SrcSecondPointY")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("SrcThirdPointX")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("SrcThirdPointY")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("DstFirstPointX")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("DstFirstPointY")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("DstSecondPointX")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("DstSecondPointY")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("DstThirdPointX")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("DstThirdPointY")) == IImageComputeFnDef::ParamType::Double);

			Assert::AreEqual(_fnDef->ConvertParamTypeToStr(IImageComputeFnDef::ParamType::String), _fnDef->GetParamValType("RootFolder"));

			Assert::IsFalse(_fnDef->IsParamValMinSet("RootFolder"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("RootFolder"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("IJC"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("IJC"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("IJF"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("IJF"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("ImageRef"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("ImageRef"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("SrcFirstPointX"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("SrcFirstPointY"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("SrcSecondPointX"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("SrcSecondPointY"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("SrcThirdPointX"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("SrcThirdPointY"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("DstFirstPointX"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("DstFirstPointY"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("DstSecondPointX"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("DstSecondPointY"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("DstThirdPointX"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("DstThirdPointY"));

			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("SrcFirstPointX"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("SrcFirstPointY"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("SrcSecondPointX"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("SrcSecondPointY"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("SrcThirdPointX"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("SrcThirdPointY"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("DstFirstPointX"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("DstFirstPointY"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("DstSecondPointX"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("DstSecondPointY"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("DstThirdPointX"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("DstThirdPointY"));

			Assert::AreEqual("no", _fnDef->GetParamDefaultVal("StopProc"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("RootFolder"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("IJC"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("IJF"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("ImageRef"));
			Assert::AreEqual("0.0", _fnDef->GetParamDefaultVal("SrcFirstPointX"));
			Assert::AreEqual("0.0", _fnDef->GetParamDefaultVal("SrcFirstPointY"));
			Assert::AreEqual("100.0", _fnDef->GetParamDefaultVal("SrcSecondPointX"));
			Assert::AreEqual("0.0", _fnDef->GetParamDefaultVal("SrcSecondPointY"));
			Assert::AreEqual("0.0", _fnDef->GetParamDefaultVal("SrcThirdPointX"));
			Assert::AreEqual("100.0", _fnDef->GetParamDefaultVal("SrcThirdPointY"));
			Assert::AreEqual("200.0", _fnDef->GetParamDefaultVal("DstFirstPointX"));
			Assert::AreEqual("200.0", _fnDef->GetParamDefaultVal("DstFirstPointY"));
			Assert::AreEqual("300.0", _fnDef->GetParamDefaultVal("DstSecondPointX"));
			Assert::AreEqual("0.0", _fnDef->GetParamDefaultVal("DstSecondPointY"));
			Assert::AreEqual("0.0", _fnDef->GetParamDefaultVal("DstThirdPointX"));
			Assert::AreEqual("300.0", _fnDef->GetParamDefaultVal("DstThirdPointY"));

			Assert::AreEqual("Stop", _fnDef->GetParamLabel("StopProc"));
			Assert::AreEqual("Root folder", _fnDef->GetParamLabel("RootFolder"));
			Assert::AreEqual("IJC id", _fnDef->GetParamLabel("IJC"));
			Assert::AreEqual("IJF id", _fnDef->GetParamLabel("IJF"));
			Assert::AreEqual("ImageRef", _fnDef->GetParamLabel("ImageRef"));
			Assert::AreEqual("SrcFirstPointX", _fnDef->GetParamLabel("SrcFirstPointX"));
			Assert::AreEqual("SrcFirstPointY", _fnDef->GetParamLabel("SrcFirstPointY"));
			Assert::AreEqual("SrcSecondPointX", _fnDef->GetParamLabel("SrcSecondPointX"));
			Assert::AreEqual("SrcSecondPointY", _fnDef->GetParamLabel("SrcSecondPointY"));
			Assert::AreEqual("SrcThirdPointX", _fnDef->GetParamLabel("SrcThirdPointX"));
			Assert::AreEqual("SrcThirdPointY", _fnDef->GetParamLabel("SrcThirdPointY"));
			Assert::AreEqual("DstFirstPointX", _fnDef->GetParamLabel("DstFirstPointX"));
			Assert::AreEqual("DstFirstPointY", _fnDef->GetParamLabel("DstFirstPointY"));
			Assert::AreEqual("DstSecondPointX", _fnDef->GetParamLabel("DstSecondPointX"));
			Assert::AreEqual("DstSecondPointY", _fnDef->GetParamLabel("DstSecondPointY"));
			Assert::AreEqual("DstThirdPointX", _fnDef->GetParamLabel("DstThirdPointX"));
			Assert::AreEqual("DstThirdPointY", _fnDef->GetParamLabel("DstThirdPointY"));

			Assert::AreEqual("Do not process this step or any further steps", _fnDef->GetParamDesc("StopProc"));
			Assert::AreEqual("folder for project root", _fnDef->GetParamDesc("RootFolder"));
			Assert::AreEqual("GUID for job collection", _fnDef->GetParamDesc("IJC"));
			Assert::AreEqual("GUID for job file", _fnDef->GetParamDesc("IJF"));
			Assert::AreEqual("name of input image in ImageFolder without filetype", _fnDef->GetParamDesc("ImageRef"));
			Assert::AreEqual("SrcFirstPointX: X coordinate of first point of source image in range of 0 to image width", _fnDef->GetParamDesc("SrcFirstPointX"));
			Assert::AreEqual("SrcFirstPointY: Y coordinate of first point of source image in range of 0 to image height", _fnDef->GetParamDesc("SrcFirstPointY"));
			Assert::AreEqual("SrcSecondPointX: X coordinate of second point of source image in range of 0 to image width", _fnDef->GetParamDesc("SrcSecondPointX"));
			Assert::AreEqual("SrcSecondPointY: Y coordinate of second point of source image in range of 0 to image height", _fnDef->GetParamDesc("SrcSecondPointY"));
			Assert::AreEqual("SrcThirdPointX: X coordinate of third point of source image in range of 0 to image width", _fnDef->GetParamDesc("SrcThirdPointX"));
			Assert::AreEqual("SrcThirdPointY: Y coordinate of third point of source image in range of 0 to image height", _fnDef->GetParamDesc("SrcThirdPointY"));
			Assert::AreEqual("DstFirstPointX: X coordinate of first point of destination image in range of 0 to image width", _fnDef->GetParamDesc("DstFirstPointX"));
			Assert::AreEqual("DstFirstPointY: Y coordinate of first point of destination image in range of 0 to image height", _fnDef->GetParamDesc("DstFirstPointY"));
			Assert::AreEqual("DstSecondPointX: X coordinate of second point of destination image in range of 0 to image width", _fnDef->GetParamDesc("DstSecondPointX"));
			Assert::AreEqual("DstSecondPointY: Y coordinate of second point of destination image in range of 0 to image height", _fnDef->GetParamDesc("DstSecondPointY"));
			Assert::AreEqual("DstThirdPointX: X coordinate of third point of destination image in range of 0 to image width", _fnDef->GetParamDesc("DstThirdPointX"));
			Assert::AreEqual("DstThirdPointY: Y coordinate of third point of destination image in range of 0 to image height", _fnDef->GetParamDesc("DstThirdPointY"));
		}

		TEST_METHOD(TransformImgRunTest)
		{
			Assert::IsNotNull(_fn);
			Assert::IsTrue(_fn->IsValid());

			Assert::IsTrue(_fn->InitCall(0, ".bmp", true, true));

			Assert::IsTrue(_fn->SetParamBool("StopProc", false));
			Assert::IsTrue(_fn->SetParamStr("RootFolder", "..\\..\\..\\TestImages"));
			Assert::IsTrue(_fn->SetParamStr("IJC", "IJC"));
			Assert::IsTrue(_fn->SetParamStr("IJF", "IJF"));
			Assert::IsTrue(_fn->SetParamStr( "ImageRef", "TransformTest"));
			Assert::IsTrue(_fn->SetParamDouble("SrcFirstPointX", 0.0));
			Assert::IsTrue(_fn->SetParamDouble("SrcFirstPointY", 0.0));
			Assert::IsTrue(_fn->SetParamDouble("SrcSecondPointX", 100.0));
			Assert::IsTrue(_fn->SetParamDouble("SrcSecondPointY", 0.0));
			Assert::IsTrue(_fn->SetParamDouble("SrcThirdPointX", 0.0));
			Assert::IsTrue(_fn->SetParamDouble("SrcThirdPointY", 100.0));
			Assert::IsTrue(_fn->SetParamDouble("DstFirstPointX", 200.0));
			Assert::IsTrue(_fn->SetParamDouble("DstFirstPointY", 200.0));
			Assert::IsTrue(_fn->SetParamDouble("DstSecondPointX", 300.0));
			Assert::IsTrue(_fn->SetParamDouble("DstSecondPointY", 0.0));
			Assert::IsTrue(_fn->SetParamDouble("DstThirdPointX", 0.0));
			Assert::IsTrue(_fn->SetParamDouble("DstThirdPointY", 300.0));

			Assert::IsTrue(_fn->ValidateCall());
			Assert::IsTrue(_fn->DoCall());
		}
	};
}